"""
法律知识问答系统主配置文件
从原config.yaml转换而来，使用Python数据类定义配置结构
支持从环境变量加载敏感配置信息
"""

import os
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
from dotenv import load_dotenv

# 加载.env文件中的环境变量
load_dotenv()

# ==================== 系统基础配置 ====================
@dataclass
class SystemConfig:
    """系统基础配置"""
    name: str = "Legal Knowledge QA System"
    version: str = "1.0.0"
    environment: str = "development"  # development, production

# ==================== 向量存储配置 ====================
@dataclass
class VectorStoreConfig:
    """向量存储配置"""
    type: str = "faiss"  # faiss, milvus
    # 注意：实际配置在 .env 文件中

# ==================== 模型配置 ====================
@dataclass
class EmbeddingModelConfig:
    """Embedding模型配置"""
    model_name: str = "Qwen/Qwen3-Embedding-0.6B"
    model_path: str = ""  # 如果使用本地模型
    device: str = "cuda"  # cuda, cpu
    batch_size: int = 32
    max_length: int = 512

@dataclass
class RerankerModelConfig:
    """Reranker模型配置"""
    model_name: str = "Qwen/Qwen3-Reranker-0.6B"
    model_path: str = ""  # 如果使用本地模型
    device: str = "cuda"
    batch_size: int = 16
    max_length: int = 512
    top_k: int = 5  # 重排序后保留的文档数量

@dataclass
class LLMModelConfig:
    """LLM模型配置"""
    model_name: str = "Qwen/Qwen3-8B-Instruct"
    model_path: str = ""  # 如果使用本地模型
    device: str = "cuda"
    max_new_tokens: int = 512
    temperature: float = 0.1
    top_p: float = 0.9
    do_sample: bool = True

@dataclass
class ModelsConfig:
    """模型配置集合"""
    embedding: EmbeddingModelConfig = EmbeddingModelConfig()
    reranker: RerankerModelConfig = RerankerModelConfig()
    llm: LLMModelConfig = LLMModelConfig()

# ==================== RAG流程配置 ====================
@dataclass
class HybridSearchConfig:
    """混合检索配置"""
    enabled: bool = True
    dense_weight: float = 0.7
    sparse_weight: float = 0.3

@dataclass
class RetrievalConfig:
    """检索阶段配置"""
    initial_k: int = 20  # 初始检索数量
    similarity_threshold: float = 0.5
    hybrid_search: HybridSearchConfig = HybridSearchConfig()

@dataclass
class RerankingConfig:
    """重排序阶段配置"""
    enabled: bool = True
    final_k: int = 5  # 最终保留的文档数量

@dataclass
class GenerationConfig:
    """生成阶段配置"""
    max_context_length: int = 2048
    include_sources: bool = True

@dataclass
class RAGConfig:
    """RAG流程配置"""
    retrieval: RetrievalConfig = RetrievalConfig()
    reranking: RerankingConfig = RerankingConfig()
    generation: GenerationConfig = GenerationConfig()

# ==================== 提示词配置 ====================
@dataclass
class PromptsConfig:
    """提示词配置"""
    # 查询扩展提示词
    query_expansion: str = """你是一个专业的法律助理。你的任务是为用户的真实问题生成几个不同的搜索查询，以便从法律知识库中检索最相关的信息。
考虑问题的同义词、上位词、下位词以及不同的问法。生成的查询应该全面且直接针对法律概念。

用户问题：{original_question}

请生成3个不同的搜索查询，直接输出为JSON列表格式：
{"queries": ["query1", "query2", "query3"]}"""
    
    # 系统提示词
    system_prompt: str = """你是一名严谨、专业的法律AI助手。你严格根据<context>标签中提供的相关法律条文、司法解释和案例来回答问题。
- 你的回答必须准确、清晰、无歧义，并符合中国的法律法规。
- 如果上下文中的信息不足以完全回答问题，你必须明确说明"根据现有资料，无法完全确定..."，并可以基于一般法律原则进行谨慎推理，但必须提示用户这并非最终法律意见。
- **最重要的一点：你的每一个事实性陈述，都必须直接引用或源自提供的上下文。**
- 在回答的最后，请列出你所引用的上下文来源（文档名称或编号）。
- 严禁编造不存在的信息或使用外部知识。"""
    
    # 用户提示词模板
    user_prompt_template: str = """<context>
{formatted_context}
</context>

用户问题：{user_question}

请根据上述上下文提供专业的法律回答。"""

# ==================== 数据配置 ====================
@dataclass
class DataConfig:
    """数据配置"""
    raw_data_path: str = "datasets/raw/"
    processed_data_path: str = "datasets/processed/"
    chunk_size: int = 512
    chunk_overlap: int = 50

# ==================== API配置 ====================
@dataclass
class RateLimitConfig:
    """限流配置"""
    enabled: bool = True
    requests_per_minute: int = 60

@dataclass
class CORSConfig:
    """CORS配置"""
    enabled: bool = True
    allow_origins: List[str] = None
    allow_methods: List[str] = None
    allow_headers: List[str] = None
    
    def __post_init__(self):
        if self.allow_origins is None:
            self.allow_origins = ["*"]
        if self.allow_methods is None:
            self.allow_methods = ["GET", "POST"]
        if self.allow_headers is None:
            self.allow_headers = ["*"]

@dataclass
class APIConfig:
    """API配置"""
    host: str = "0.0.0.0"
    port: int = 8000
    workers: int = 1
    rate_limit: RateLimitConfig = RateLimitConfig()
    cors: CORSConfig = CORSConfig()

# ==================== 日志配置 ====================
@dataclass
class FileLogConfig:
    """文件日志配置"""
    enabled: bool = True
    path: str = "logs/system.log"
    max_size: str = "100MB"
    backup_count: int = 5

@dataclass
class ConsoleLogConfig:
    """控制台日志配置"""
    enabled: bool = True

@dataclass
class LoggingConfig:
    """日志配置"""
    level: str = "INFO"
    format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    file: FileLogConfig = FileLogConfig()
    console: ConsoleLogConfig = ConsoleLogConfig()

# ==================== 缓存配置 ====================
@dataclass
class CacheConfig:
    """缓存配置"""
    enabled: bool = True
    type: str = "memory"  # memory, redis
    size: int = 1000
    ttl: int = 3600

# ==================== 监控配置 ====================
@dataclass
class HealthCheckConfig:
    """健康检查配置"""
    enabled: bool = True
    interval: int = 30  # 秒

@dataclass
class MonitoringConfig:
    """监控配置"""
    enabled: bool = True
    metrics: List[str] = None
    health_check: HealthCheckConfig = HealthCheckConfig()
    
    def __post_init__(self):
        if self.metrics is None:
            self.metrics = [
                "response_time",
                "throughput", 
                "error_rate",
                "memory_usage"
            ]

# ==================== 安全配置 ====================
@dataclass
class APIKeyConfig:
    """API密钥认证配置"""
    enabled: bool = False
    key: str = ""

@dataclass
class InputValidationConfig:
    """输入验证配置"""
    max_query_length: int = 1000
    allowed_characters: str = r"[\u4e00-\u9fff\w\s，。；：""''（）【】《》\-\.\,\;\:\!\?]"

@dataclass
class SecurityConfig:
    """安全配置"""
    api_key: APIKeyConfig = APIKeyConfig()
    input_validation: InputValidationConfig = InputValidationConfig()

# ==================== 主配置类 ====================
@dataclass
class Config:
    """法律知识问答系统主配置类"""
    system: SystemConfig = SystemConfig()
    vector_store: VectorStoreConfig = VectorStoreConfig()
    models: ModelsConfig = ModelsConfig()
    rag: RAGConfig = RAGConfig()
    prompts: PromptsConfig = PromptsConfig()
    data: DataConfig = DataConfig()
    api: APIConfig = APIConfig()
    logging: LoggingConfig = LoggingConfig()
    cache: CacheConfig = CacheConfig()
    monitoring: MonitoringConfig = MonitoringConfig()
    security: SecurityConfig = SecurityConfig()

# ==================== 全局配置实例 ====================
# 创建全局配置实例
config = Config()

# ==================== 配置工具函数 ====================
def get_config() -> Config:
    """获取全局配置实例"""
    return config

def update_config_from_env():
    """从环境变量更新配置"""
    # 可以根据需要从环境变量更新特定配置项
    # 例如：
    # config.api.host = os.getenv("API_HOST", config.api.host)
    # config.api.port = int(os.getenv("API_PORT", config.api.port))
    pass

# 初始化时从环境变量更新配置
update_config_from_env()
# ==================== 数据集生成API配置 ====================
# 从环境变量中获取敏感配置
API_KEY = os.getenv("API_KEY", "")
BASE_URL = os.getenv("BASE_URL", "")
DEFAULT_MODEL = os.getenv("DEFAULT_MODEL", "qwen3-235b-a22b-instruct-2507")

# 验证必要的配置是否存在
if not API_KEY:
    raise ValueError("API_KEY 未在环境变量中设置，请检查.env文件")

if not BASE_URL:
    raise ValueError("BASE_URL 未在环境变量中设置，请检查.env文件")


